package com.dynamic.model.util.redis;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;

import com.dynamic.model.util.common.SpringBeanUtils;
import org.springframework.context.ApplicationContext;


/**
 * 自定义缓存管理基类，当更改缓存时，更改此类即可
 * 注意：现阶段缓存时用容器缓存的，需要在启动时servlet监听里面调用初始化缓存变量，调用：
 * CacheManage.getInstance().init(event.getServletContext());//初始化所有缓存使用的变量
 * 
 * 在这之后，再执行具体的缓存，存入需要缓存的东西
 *
 */
public class CacheManager{
	private ApplicationContext springCtx;
	
	private ObjectRedisCache objectRedisCache;
	
	public final static String SEPARATOR = "-";//缓存的key的拼接分离符
	
	private static CacheManager instance;
	public static CacheManager getInstance(){
		if(instance==null)
			instance=new CacheManager();
		return instance;
	}
	
	private CacheManager() {
		super();
	}

	public ApplicationContext getSpringCtx() {
		return springCtx;
	}

	/**
	 * 容器启动时，在监听中初始化servletContext
	 */
	public void init(){
		this.springCtx = SpringBeanUtils.getApplicationContext();
		
		//字符串形式的redis缓存
		if(objectRedisCache == null){
			objectRedisCache = (ObjectRedisCache)springCtx.getBean("objectRedisCache");
		}
	}
	
	/**
	 * 根据属性名称获取对应的缓存值
	 * @param key
	 * @return
	 */
	public Object getAttributeObj(String key){
		Object object = objectRedisCache.getCacheObject(key);
		return object;
	}
	
	/**
	 * 设置缓存值
	 * @param key
	 * @param object
	 */
	public void setAttributeObj(String key, Object object){
		if(object != null){
			objectRedisCache.setCacheObject(key, object);
		}
	}
	
	/**
	 * 设置缓存值，指定时间失效
	 * @param key
	 * @param object
	 * @param expiry	 过期时间(毫秒)
	 */
	public void setAttributeObj(String key, Object object, long expiry){
		if(object != null){
			objectRedisCache.setCacheObject(key, object, expiry);
		}
	}
	
	/***************缓存map形式的数据*****************/
	/**
	 * 获取缓存的map数据，map的key为String类型
	 * @param key
	 * @return
	 */
	public Map<String, ? extends Object> getAttributeMap(String key){
		return getAttributeMap(key, String.class);
	}
	
	/**
	 * 获取缓存的map数据，map的key为Long类型
	 * @param key
	 * @return
	 */
	public Map<Long, ? extends Object> getAttributeMapLong(String key){
		return getAttributeMap(key, Long.class);
	}
	
	/**
	 * 获取缓存的map数据，
	 * @param key
	 * @param hashKeyClazz
	 * @return
	 */
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public <T> Map<T, ? extends Object> getAttributeMap(String key, Class<T> hashKeyClazz){
		Map object = objectRedisCache.getCacheMap(key);
		if(object != null){
			Map resMap = new HashMap();
			if(hashKeyClazz == Long.class){
				for(Object hashKey: object.keySet()){
					resMap.put(Long.parseLong((String)hashKey), object.get(hashKey));
				}
				return resMap;
			}
		}
		return object;
	}
	
	/**
	 * 获取缓存的单个map数据
	 * @param key
	 * @param hashKey
	 * @return
	 */
	public Object getAttributeMap(String key, String hashKey){
		return objectRedisCache.getCacheMapValue(key, hashKey);
	}
	
	/**
	 * 获取缓存的单个map数据
	 * @param key
	 * @param hashKey
	 * @return
	 */
	public Object getAttributeMap(String key, Long hashKey){
		return getAttributeMap(key, hashKey.toString());
//		return objectRedisCache.getCacheLongMapValue(key, hashKey);
	}
	
	/**
	 * 缓存map格式数据
	 * @param key
	 * @param map
	 */
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public void setAttributeMap(String key, Map map){
		removeAttribute(key);//清空当前map
		if(map != null && map.size() >= 1){
			Iterator<Entry> entryIterator = map.entrySet().iterator();
			while(entryIterator.hasNext()){
				Entry entry = entryIterator.next();
				Object jsonVal = entry.getValue();
				if(entry.getKey() instanceof Long){
					setAttributeMap(key, (Long)entry.getKey(), jsonVal);
				}else if(entry.getKey() instanceof String){
					setAttributeMap(key, (String)entry.getKey(), jsonVal);
				}
			}
		}
	}
	
	/**
	 * 更新缓存map的单个值
	 * @param key	缓存key
	 * @param hashKey	map对应的key
	 * @param value		map里的值
	 */
	public void setAttributeMap(String key, Long hashKey, Object value){
//		objectRedisCache.setCacheLongMapValue(key, hashKey, value);
		setAttributeMap(key, hashKey.toString(), value);
	}
	
	/**
	 * 更新缓存map的单个值
	 * @param key	缓存key
	 * @param hashKey	map对应的key
	 * @param value		map里的值
	 */
	public void setAttributeMap(String key, String hashKey, Object value){
		objectRedisCache.setCacheMapValue(key, hashKey, value);
	}
	
	/**
	 * 从缓存map中删除数据
	 * @param key
	 * @param hashKeys
	 */
	public void removeAttributeMap(String key, Long... hashKeys){
		String[] strKeys = new String[hashKeys.length];
		for(int i = 0; i < hashKeys.length; i ++){
			strKeys[i] = hashKeys[i].toString();
		}
		objectRedisCache.removeCacheMapKeys(key, strKeys);
	}
	
	/**
	 * 从缓存map中删除数据
	 * @param key
	 * @param hashKeys
	 */
	public void removeAttributeMap(String key, String... hashKeys){
		objectRedisCache.removeCacheMapKeys(key, hashKeys);
	}
	
	/**
	 * 将对应属性从缓存中移除
	 * @param key
	 */
	public void removeAttribute(String key){
		objectRedisCache.removeCache(key);
	}
	
	/******************************************针对整个项目的缓存，例如mpf里面缓存了，然后在spf里面可以取出来使用******************************************/
	/**
	 * 根据属性名称获取对应的缓存值，针对整个项目的缓存，例如mpf里面缓存了，然后在spf里面可以取出来使用
	 * @param key
	 * @return
	 */
	public Object getAttributeObjGlobal(String key){
		return objectRedisCache.getCacheObject(getGlobalPrjName(), key);
	}
	
	/**
	 * 设置缓存值，针对整个项目的缓存，例如mpf里面缓存了，然后在spf里面可以取出来使用
	 * @param key
	 * @param object
	 */
	public void setAttributeObjGlobal(String key, Object object){
		if(object != null){
			objectRedisCache.setCacheObject(getGlobalPrjName(), key, object);
		}
	}
	
	/**
	 * 设置缓存值，指定时间失效
	 * @param key
	 * @param object
	 * @param expiry	 过期时间(毫秒)
	 */
	public void setAttributeObjGlobal(String key, Object object, long expiry){
		if(object != null){
			objectRedisCache.setCacheObject(getGlobalPrjName(), key, object, expiry);
		}
	}
	
	/**
	 * 将对应属性从缓存中移除，针对整个项目的缓存，例如mpf里面缓存了，然后在spf里面可以取出来使用
	 * @param key
	 */
	public void removeAttributeGlobal(String key){
		objectRedisCache.removeCache(getGlobalPrjName(), key);
	}
	
	/***************缓存map形式的数据*****************/
	/**
	 * 获取缓存的map数据，map的key为String类型
	 * @param key
	 * @return
	 */
	public Map<String, ? extends Object> getAttributeMapGlobal(String key){
		return getAttributeMapGlobal(key, String.class);
	}
	
	/**
	 * 获取缓存的map数据，map的key为Long类型
	 * @param key
	 * @return
	 */
	public Map<Long, ? extends Object> getAttributeMapLongGlobal(String key){
		return getAttributeMapGlobal(key, Long.class);
	}
	
	/**
	 * 获取缓存的map数据，
	 * @param key
	 * @param hashKeyClazz
	 * @return
	 */
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public <T> Map<T, ? extends Object> getAttributeMapGlobal(String key, Class<T> hashKeyClazz){
		Map object = objectRedisCache.getCacheMap(getGlobalPrjName(), key);
		if(object != null){
			Map resMap = new HashMap();
			if(hashKeyClazz == Long.class){
				for(Object hashKey: object.keySet()){
					resMap.put(Long.parseLong((String)hashKey), object.get(hashKey));
				}
				return resMap;
			}
		}
		return object;
	}
	
	/**
	 * 获取缓存的单个map数据
	 * @param key
	 * @param hashKey
	 * @return
	 */
	public Object getAttributeMapGlobal(String key, String hashKey){
		return objectRedisCache.getCacheMapValue(getGlobalPrjName(), key, hashKey);
	}
	
	/**
	 * 获取缓存的单个map数据
	 * @param key
	 * @param hashKey
	 * @return
	 */
	public Object getAttributeMapGlobal(String key, Long hashKey){
//		return objectRedisCache.getCacheLongMapValue(getGlobalPrjName(), key, hashKey);
		return getAttributeMapGlobal(key, hashKey.toString());
	}
	
	/**
	 * 缓存map格式数据
	 * @param key
	 * @param map
	 */
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public void setAttributeMapGlobal(String key, Map map){
		removeAttributeGlobal(key);//清空当前缓存map
		if(map != null && map.size() >= 1){
			Iterator<Entry> entryIterator = map.entrySet().iterator();
			while(entryIterator.hasNext()){
				Entry entry = entryIterator.next();
				Object jsonVal = entry.getValue();
				if(entry.getKey() instanceof Long){
					setAttributeMapGlobal(key, (Long)entry.getKey(), jsonVal);
				}else if(entry.getKey() instanceof String){
					setAttributeMapGlobal(key, (String)entry.getKey(), jsonVal);
				}
			}
		}
	}
	
	/**
	 * 更新缓存map的单个值
	 * @param key	缓存key
	 * @param hashKey	map对应的key
	 * @param value		map里的值
	 */
	public void setAttributeMapGlobal(String key, Long hashKey, Object value){
		setAttributeMapGlobal(key, hashKey.toString(), value);
	}
	
	/**
	 * 更新缓存map的单个值
	 * @param key	缓存key
	 * @param hashKey	map对应的key
	 * @param value		map里的值
	 */
	public void setAttributeMapGlobal(String key, String hashKey, Object value){
		objectRedisCache.setCacheMapValue(getGlobalPrjName(), key, hashKey, value);
	}
	
	/**
	 * 从缓存map中删除数据
	 * @param key
	 * @param hashKeys
	 */
	public void removeAttributeMapGlobal(String key, Long... hashKeys){
		String[] strKeys = new String[hashKeys.length];
		for(int i = 0; i < hashKeys.length; i ++){
			strKeys[i] = hashKeys[i].toString();
		}
		objectRedisCache.removeCacheMapKeys(getGlobalPrjName(), key, strKeys);
	}
	
	/**
	 * 从缓存map中删除数据
	 * @param key
	 * @param hashKeys
	 */
	public void removeAttributeMapGlobal(String key, String... hashKeys){
		objectRedisCache.removeCacheMapKeys(getGlobalPrjName(), key, hashKeys);
	}
	
	/**
	 * 获取整个项目的名称
	 * @return
	 */
	private String getGlobalPrjName(){
		String prefix = objectRedisCache.getPrefix();
		return prefix.split("_")[0];
	}
}
